﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PCS.Util
{
    static class DateUtil
    {
        public static Dictionary<System.DateTime, System.DateTime> DivideDateRegions(System.DateTime date_from, System.DateTime date_to)
        {
            Dictionary<System.DateTime, System.DateTime> dict = new Dictionary<DateTime, DateTime>();
            //KeyValuePair<System.DateTime, System.DateTime> kvp = new KeyValuePair<System.DateTime, System.DateTime>();
            System.DateTime indicator;

            indicator = date_from;

            while (indicator.Year != date_to.Year || indicator.Month != date_to.Month)
            {
                dict.Add(indicator, getMonthEnd(indicator));
                indicator = getMonthStart(indicator);
            }

            dict.Add(indicator, date_to);

            return dict;
        }

        public static System.DateTime getMonthStart(System.DateTime start)
        {
            return DateTime.Parse(start.ToString("yyyy-MM-01")).AddMonths(1);
        }
        public static System.DateTime getMonthEnd(System.DateTime start)
        {
            return DateTime.Parse(start.ToString("yyyy-MM-01")).AddMonths(1).AddDays(-1);
        }


        public static int DateDiff(DateTime DateTime1, DateTime DateTime2)
        {
            int dateDiff;

            TimeSpan ts1 = new TimeSpan(DateTime1.Ticks);
            TimeSpan ts2 = new TimeSpan(DateTime2.Ticks);
            TimeSpan ts = ts1.Subtract(ts2).Duration();
            dateDiff = ts.Days;
            return dateDiff;
        }

        public static System.DateTime ChangeNonHoliday(System.DateTime dt, Common.DATETYPE dateType)
        {
            Dictionary<System.DateTime, bool> holidayDict;
            holidayDict = GetHolidayList();
            return Change(holidayDict, dt, dateType);
        }

        private static System.DateTime Change(System.Collections.Generic.Dictionary<System.DateTime,bool> dict, System.DateTime dt, Common.DATETYPE dateType )
        {
            int days;

            if (dateType == Common.DATETYPE.START)
            {
                days = 1;
            }
            else
            {
                days = -1;
            }

            if (dict.Keys.Contains(dt))
            {
                if (IsHoliday(dict, dt))
                {
                    return Change(dict,dt.AddDays(days),dateType);
                }
                else
                {
                    return dt;
                }
            }
            else
            {
                if (IsWeekend(dt))
                    return Change(dict, dt.AddDays(days), dateType);
                else
                    return dt;
            }
        }

        private static bool IsHoliday(System.Collections.Generic.Dictionary<System.DateTime,bool> dict, System.DateTime dt)
        {
            if (dict[dt])
                return true;
            else
                return false;

        }

        private static bool IsWeekend(System.DateTime dt)
        {
            if (dt.DayOfWeek == System.DayOfWeek.Saturday || dt.DayOfWeek == System.DayOfWeek.Sunday)
                return true;
            else
                return false;
        }

        public static Dictionary<System.DateTime, bool> GetHolidayList()
        {
            System.Collections.Generic.Dictionary<System.DateTime, bool> holidayDict = new Dictionary<DateTime, bool>();
            //set holiday info, if holiday, set true, otherwise set false.
            holidayDict.Add(DateTime.Parse("2012/10/1"), true);
            holidayDict.Add(DateTime.Parse("2012/10/2"), true);
            holidayDict.Add(DateTime.Parse("2012/10/3"), true);
            holidayDict.Add(DateTime.Parse("2012/10/4"), true);
            holidayDict.Add(DateTime.Parse("2012/10/5"), true);
            holidayDict.Add(DateTime.Parse("2012/9/30"), false);


            holidayDict.Add(DateTime.Parse("2013/1/1"), true);
            holidayDict.Add(DateTime.Parse("2013/1/2"), true);
            holidayDict.Add(DateTime.Parse("2013/1/3"), true);
            holidayDict.Add(DateTime.Parse("2013/1/5"), false);
            holidayDict.Add(DateTime.Parse("2013/1/6"), false);

            holidayDict.Add(DateTime.Parse("2013/2/9"), true);
            holidayDict.Add(DateTime.Parse("2013/2/10"), true);
            holidayDict.Add(DateTime.Parse("2013/2/11"), true);
            holidayDict.Add(DateTime.Parse("2013/2/12"), true);
            holidayDict.Add(DateTime.Parse("2013/2/13"), true);
            holidayDict.Add(DateTime.Parse("2013/2/14"), true);
            holidayDict.Add(DateTime.Parse("2013/2/15"), true);
            holidayDict.Add(DateTime.Parse("2013/2/16"), false);
            holidayDict.Add(DateTime.Parse("2013/2/17"), false);

            holidayDict.Add(DateTime.Parse("2013/4/4"), true);
            holidayDict.Add(DateTime.Parse("2013/4/5"), true);
            holidayDict.Add(DateTime.Parse("2013/4/6"), true);
            holidayDict.Add(DateTime.Parse("2013/4/7"), false);

            holidayDict.Add(DateTime.Parse("2013/4/29"), true);
            holidayDict.Add(DateTime.Parse("2013/5/1"), true);
            holidayDict.Add(DateTime.Parse("2013/4/27"), false);
            holidayDict.Add(DateTime.Parse("2013/4/28"), false);

            holidayDict.Add(DateTime.Parse("2013/6/10"), true);
            holidayDict.Add(DateTime.Parse("2013/6/11"), true);
            holidayDict.Add(DateTime.Parse("2013/6/12"), true);
            holidayDict.Add(DateTime.Parse("2013/6/8"), false);
            holidayDict.Add(DateTime.Parse("2013/6/9"), false);

            holidayDict.Add(DateTime.Parse("2013/9/19"), true);
            holidayDict.Add(DateTime.Parse("2013/9/20"), true);
            holidayDict.Add(DateTime.Parse("2013/9/22"), false);

            holidayDict.Add(DateTime.Parse("2013/10/1"), true);
            holidayDict.Add(DateTime.Parse("2013/10/2"), true);
            holidayDict.Add(DateTime.Parse("2013/10/3"), true);
            holidayDict.Add(DateTime.Parse("2013/10/4"), true);
            holidayDict.Add(DateTime.Parse("2013/10/5"), true);
            holidayDict.Add(DateTime.Parse("2013/10/6"), true);
            holidayDict.Add(DateTime.Parse("2013/10/7"), true);
            holidayDict.Add(DateTime.Parse("2013/9/29"), false);
            holidayDict.Add(DateTime.Parse("2013/10/12"), false);

            return holidayDict;
        }

        public static int TotalWorkday(DateTime AStart, DateTime AEnd)
        {
            TimeSpan vTimeSpan = new TimeSpan(AEnd.Ticks - AStart.Ticks);

            int Result = ((int)vTimeSpan.TotalDays / 7) * 5;

            for (int i = 0; i <= vTimeSpan.TotalDays % 7; i++)
                switch (AStart.AddDays(i).DayOfWeek)
                {
                    case DayOfWeek.Saturday:
                    case DayOfWeek.Sunday:
                        break;
                    default:
                        Result++;
                        break;
                }
            
            return Result - TotalHoliday(AStart,AEnd);
        }

        private static int TotalHoliday(DateTime AStart, DateTime AEnd)
        {
            //for (DateTime d = AStart; d < AEnd; d.AddDays(1))
            //{
                
            //}
            Dictionary<DateTime, bool> dict = GetHolidayList();
            int cnt =0;

            foreach (DateTime item in dict.Keys)
            {
                if (AStart.CompareTo(item) <= 0 && AEnd.CompareTo(item) >= 0)
                {
                    cnt++;
                }
            }

            return cnt;
        }

    }
}
